`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2020/12/14 22:23:36
// Design Name: 
// Module Name: test_dma
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module test_dma;
reg set_state,clk,rstn,cpu_to_dma_enable,cpu_to_dma_valid,mem_to_dma_enable,mem_to_dma_valid,buf1_fifo_state,buf2_fifo_state,buf1_readp,buf2_readp,buf1_writep,buf2_writep;
reg [3:0]mem_value,mem_data_in;
reg [7:0]cpu_value,cpu_data_in;
wire [4:0] buf1_cnt,buf2_cnt;
wire buf1_empty,buf1_full,buf2_empty,buf2_full,state,buf1_r,buf2_r;
wire [3:0]mem_data_out;
wire [7:0]cpu_data_out;
wire [2:0] buf1_addr,buf2_addr;
fifo_4to8 obj1(.clk(clk),.rstn(rstn),.cnt(buf1_cnt),.readp(buf1_readp),.writep(buf1_writep));
fifo_8to4 obj2(.clk(clk),.rstn(rstn),.cnt(buf2_cnt),.readp(buf2_readp),.writep(buf2_writep));
dma U1 (.clk(clk),.rstn(rstn),.set_state(set_state),.state(state),.cpu_to_dma_enable(cpu_to_dma_enable),.cpu_to_dma_valid(cpu_to_dma_valid),.mem_to_dma_enable(mem_to_dma_enable),.mem_to_dma_valid(mem_to_dma_valid),.mem_data_in(mem_data_in),.mem_data_out(mem_data_out),.cpu_data_in(cpu_data_in),.cpu_data_out(cpu_data_out),.buf1_full(buf1_full),.buf1_empty(buf1_empty),.buf2_full(buf2_full),.buf2_empty(buf2_empty),.buf1_addr(buf1_addr),.buf2_addr(buf2_addr),.buf1_r(buf1_r),.buf2_r(buf2_r));
 always@(posedge clk)begin
  if(!rstn)begin
  set_state<=$random()%2;
  cpu_to_dma_enable<=$random()%2;
  cpu_to_dma_valid<=$random()%2;
  mem_to_dma_enable<=$random()%2;
  mem_to_dma_valid<=$random()%2;
  cpu_data_in<=cpu_data_in+1;
  mem_data_in<=mem_data_in+1;
buf1_fifo_state=buf1_readp;
buf2_fifo_state=buf2_readp;
  end
  else begin
  buf1_fifo_state=1'b0;
  buf2_fifo_state=1'b1;
  cpu_data_in<=0;
  mem_data_in<=0;
  end
  end
  always@(posedge clk)begin
  if(!rstn && !state)begin
  buf1_readp=1'b0;
  buf1_writep=1'b1;
  buf2_readp=1'b1;
  buf2_writep=1'b0;
  end
  else if(!rstn && state)begin
  buf1_readp=1'b1;
  buf1_writep=1'b0;
  buf2_readp=1'b0;
  buf2_writep=1'b1;
  end
  end
task buf1_read_word;
forever begin
   @(negedge clk);
   cpu_to_dma_valid = 1;
   @(posedge clk) #5;
   cpu_to_dma_valid = 0;
end
endtask
task buf2_read_word;
forever begin
   @(negedge clk);
   mem_to_dma_valid = 1;
   @(posedge clk) #5;
   mem_to_dma_valid = 0;
end
endtask
task buf1_write_word;
input [3:0]	mem_value;
begin
   @(negedge clk);
   mem_data_in = mem_value;
   mem_to_dma_valid = 1;
   @(posedge clk);
   #5;
   mem_to_dma_valid = 0;
   end
   endtask
   task buf2_write_word;
input [7:0]	cpu_value;
begin
   @(negedge clk);
   cpu_data_in = cpu_value;
   cpu_to_dma_valid = 1;
   @(posedge clk);
   #5;
   cpu_to_dma_valid = 0;
   end
   endtask
initial begin
   clk = 0;
   mem_data_in = 0;
   cpu_data_in = 0;
end
always begin
      #10;
      clk = ~clk;
   end
initial begin
test;
end
task test;
reg [7:0] buf1_writer_counter;
reg [7:0] buf2_writer_counter;
begin
buf1_writer_counter=8'h00;
buf2_writer_counter=8'h00;
rstn=1;
clk=0;
set_state=0;
cpu_to_dma_enable=0;
cpu_to_dma_valid=0;
mem_to_dma_enable=0;
mem_to_dma_valid=0;
#50 rstn=0;
set_state=$random()%2;
cpu_to_dma_enable=$random()%2;
mem_to_dma_enable=$random()%2;
#50;
fork
repeat(5000) begin
            @(negedge clk);
            if (!buf1_full) begin
                buf1_write_word(buf1_writer_counter);
               #5;
               buf1_writer_counter = buf1_writer_counter + 1;
            end
               #50;
               end
               forever begin
                @(negedge clk);
            if (!buf1_empty) begin
               buf1_read_word;
            end  
          #50;
         end
join
fork
repeat(5000) begin      @(negedge clk);
            if (!buf2_full) begin
                buf2_write_word(buf2_writer_counter);
               #5;
               buf2_writer_counter = buf2_writer_counter + 1;
            end
               #50;
               end
               forever begin
                @(negedge clk);
            if (!buf2_empty) begin
                buf2_read_word;
            end  
          #50;
         end
   join
end
endtask
endmodule

